package org.larkdoc.controller;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.larkdoc.config.ReadConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONObject;

/**
 * 文件处理控制类
 * 
 * @author  zhangpeijun[zhangpeijun1024@qq.com]
 * @version  [v1.0.1, 2017年10月17日]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
@RestController
@RequestMapping("file")
public class FileController {
    
    private static final Logger log       = LoggerFactory.getLogger(FileController.class);
    
    @Autowired
    ReadConfig                  readConfig;
    
    /**
     * 目前支持的图片类型
     */
    String[]                    imgSuffix = {"jpg", "jpeg", "gif", "png", "bmp", "webp"};
    
    /**
     * md编辑器图片上传
     * @param file
     * @return
     * 
     * @returns JSONObject
     * @see [类、类#方法、类#成员]
     * @author  zhangpeijun[zhangpeijun1024@qq.com]<br/>
     *          2017年9月11日上午10:45:04
     */
    @RequestMapping("/upload/mdImg")
    public JSONObject upload(@RequestParam(value = "editormd-image-file", required = true) MultipartFile file) {
        JSONObject result = new JSONObject();
        // 每个图片拥有唯一名称，用于文档后台动态获取。
        String name = file.getOriginalFilename();
        String suff = name.substring(name.lastIndexOf(".") + 1, name.length());
        if (!imgSuffixSupport(suff)) {
            result.put("success", 0);
            result.put("message", "上传失败,支持文件后缀为:jpg|jpeg|gif|png|bmp|webp.");
            log.info("上传文件不支持。原文件：{}", name);
            return result;
        }
        result.put("success", 1);
        result.put("message", "上传成功.");
        String newFileName = UUID.randomUUID().toString();
        String path = readConfig.getUploadPath() + File.separatorChar + newFileName + "." + suff;
        File newFile = new File(path);
        if (!newFile.exists()) {
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(newFile);
                fos.write(file.getBytes());
            } catch (FileNotFoundException e) {
                result.put("success", 0);
                result.put("message", "上传失败.");
                log.error("FileNotFoundException ", e);
            } catch (IOException e) {
                result.put("success", 0);
                result.put("message", "上传失败.");
                log.error("IOException ", e);
            } finally {
                try {
                    if (null != fos) {
                        fos.flush();
                        fos.close();
                    }
                } catch (IOException e) {
                    result.put("success", 0);
                    result.put("message", "上传失败.");
                    log.error("IOException ", e);
                }
            }
        } else {
            result.put("success", 0);
            result.put("message", "上传失败.");
        }
        result.put("url", "/file/get/mdImg/" + newFileName + "?suffix=" + suff);
        return result;
    }
    
    @RequestMapping("/get/mdImg/{imgName}")
    public void getImg(HttpServletResponse resp, @PathVariable String imgName,
                       @RequestParam(value = "suffix", required = false, defaultValue = "") String suffix) {
        if (StringUtils.isNotBlank(imgName)) {
            resp.setHeader("Content-Type", "image/jped");
            // 图片上传的格式没法确定，只能拼接找图，http获取地址时，请求不到"."后面的类型，因此根据名称找
            File file = null;
            if (StringUtils.isNotBlank(suffix)) {
                file = new File(readConfig.getUploadPath() + File.separatorChar + imgName + "." + suffix);
            } else {
                for (String fix : imgSuffix) {
                    file = new File(readConfig.getUploadPath() + File.separatorChar + imgName + "." + fix);
                    if (file.exists()) {
                        break;
                    }
                }
            }
            if (!file.exists()) {
                log.info("找不到文件：{}", imgName);
                return;
            }
            ServletOutputStream sos = null;
            try {
                FileInputStream fis = new FileInputStream(file);
                byte[] data = readInputStream(fis);
                sos = resp.getOutputStream();
                sos.write(data);
                resp.flushBuffer();
            } catch (Exception e) {
                log.error("Exception ", e);
            } finally {
                if (null != sos) {
                    try {
                        sos.flush();
                        sos.close();
                        sos = null;
                    } catch (IOException e) {
                        log.error("ServletOutputStream close Exception ", e);
                    }
                }
            }
        }
    }
    
    private byte[] readInputStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[2048];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        inStream.close();
        return outStream.toByteArray();
    }
    
    /**
     * 判断图片格式是否支持.
     * true：支持，
     * false：不支持
     * @param suffix
     * @return
     * 
     * @returns boolean
     * @see [类、类#方法、类#成员]
     * @author  zhangpeijun[zhangpeijun1024@qq.com]<br/>
     *          2017年9月11日下午3:46:39
     */
    private boolean imgSuffixSupport(String suffix) {
        boolean match = false;
        for (String fix : imgSuffix) {
            if (fix.equals(suffix)) {
                match = true;
                break;
            }
        }
        return match;
    }
}
